#include "stdafx.h"
#include <Strsafe.h>
#include "HttpFx.h"
#include "Foxdev.h"

#define	EXP(x)		((x&0x200)?x|0xfc00:x)
#define MAX_PARAM	2048

Foxdev::Foxdev(HDEVINFO devInfo,SP_DEVICE_INTERFACE_DATA *devData):
	UsbHid(devInfo,devData){
	StringCchCopy(url,MAX_PATH,L"/kalkr/");
	StringCchCat(url,MAX_PATH,serialNum);
	accKey=0;
	offset=0;
	voltB=0;
	voltC=0;
	voltS=0;
}

void Foxdev::cleanup(void){
}
UsbHid* Foxdev::create(HDEVINFO devInfo,SP_DEVICE_INTERFACE_DATA *devData){
	return new Foxdev(devInfo,devData);
}
void Foxdev::openAll(void){
	UsbHid::openAll(create);
}
void Foxdev::sendReport(Report* buffer){
	if(buffer){
		UsbHid::sendReport(&buffer->report[3],sizeof(Report)-3);
		if(buffer->cmd==RPT_FIRMWARE)
			upgOrd=buffer->ord;
	}
}
void Foxdev::single(ushort key,ushort val){
	switch(key){
	case RPT_STEPSLO:
		steps=(steps&0xffff0000)|val;
		break;
	case RPT_STEPSHI:
		steps=(steps&0xffff)|((uint)val<<16);
		break;
	case RPT_OFFSETLO:
		offset=(offset&0xffff0000)|val;
		break;
	case RPT_OFFSETHI:
		offset=(offset&0xffff)|((uint)val<<16);
		break;
	case RPT_TICKLO:
		tick=(tick&0xffff0000)|val;
		break;
	case RPT_TICKHI:
		tick=(tick&0xffff)|((uint)val<<16);
		break;
	case RPT_VERSION:
		version=val;
		upgrade.loadBin(serialNum,val);
		break;
	case RPT_VOLTS:
		voltS=val;
		break;
	case RPT_VOLTC:
		voltC=val;
		break;
	}
}
void Foxdev::multiple(void){
	switch(report.cmd){
	case RPT_FIRMWARE:
		sendReport(upgrade.upgrade(&report));
	}
}
uint Foxdev::threadEntry(void){
	uint n=0;
	while(1){
		if(getReport(&report.report[3],sizeof(report)-3)){
			wchar_t x[1024];
			if(report.cmd&0x8000){
				multiple();
				StringCbPrintf(x,sizeof(x),_T("%x"),upgOrd);
			}else{
				ushort *e,*p=(ushort*)&report.cmd,i,v;
				for(e=p+32;p<e;){
					i=*p++;
					v=*p++;
					single(i,v);
				}
				uint t=localTick();
				if((t-n)>600){
					char b[MAX_PARAM+1];
					sprintf_s(b,MAX_PARAM,"a=%u&c=%u&f=%u&o=%u&s=%u&t=%u&v=%u",
						accKey,voltC,voltS,offset,steps,tick,version);
					n=t;
					String* o=0;
					Http* h=0;
					try{
						o=HttpFx::hostName();
						h=new HttpFx(serialNum,version);
						h->put(url,b);
					}catch(int){
					}
					if(h)
						delete h;
					if(o)
						delete o;
				}
				int a=tick+offset-t;
				if(a<0)
					a=-a;
				if(a>10){
					memset(&report,0,sizeof(report));
					report.cmd=RPT_TICKLO;
					report.ord=LOWORD(t);
					report.data[0]=RPT_TICKHI;
					report.data[1]=HIWORD(t);
					sendReport(&report);
				}else sendReport(upgrade.upgrade(0));
			}
		}
		else break;
	}
	return 0;
}